package com.youlai.boot.modules.game.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import com.youlai.boot.modules.game.model.query.GameUserInfoQuery;
import com.youlai.boot.modules.game.model.vo.GameUserInfo;
import com.youlai.boot.modules.game.model.vo.GameUserStatisticsVO;
import com.youlai.boot.modules.game.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 游戏用户信息服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class GameUserInfoServiceImpl implements GameUserInfoService {

    private final GameUserStatisticsService gameUserStatisticsService;
    private final GameUserRecordService gameUserRecordService;
    private final GameAchievementService gameAchievementService;
    private final GameLeaderboardService gameLeaderboardService;

    @Override
    public Page<GameUserInfo> getUserInfoPage(GameUserInfoQuery queryParams) {
        // 构建分页对象
        Page<GameUserInfo> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
        
        // 获取当前用户ID
        Long userId = getCurrentUserId();
        
        // 模拟查询数据
        // 在实际应用中，这里应该从数据库获取用户列表
        List<GameUserInfo> records = new ArrayList<>();
        
        // 1. 从积分排行榜获取用户基本信息和积分
        Page<GameUserInfo> userPage = gameLeaderboardService.getUserPointsPage(
                queryParams.getPageNum(), 
                queryParams.getPageSize(), 
                queryParams.getUsername());
        
        if (userPage != null && userPage.getRecords() != null) {
            records = userPage.getRecords();
            page.setTotal(userPage.getTotal());
            
            // 2. 为每个用户填充详细数据
            for (GameUserInfo user : records) {
                // 获取用户统计信息
                try {
                    GameUserStatisticsVO statistics = gameUserStatisticsService.getUserStatistics(user.getId());
                    if (statistics != null) {
                        user.setTotalGames(statistics.getTotalGames());
                        user.setTotalPlayTime(statistics.getTotalPlayTime() != null ? statistics.getTotalPlayTime().longValue() : 0L);
                        // 使用updateTime作为最后活跃时间
                        LocalDateTime lastActiveTime = getLastActiveTime(statistics);
                        user.setLastActive(lastActiveTime);
                        
                        // 计算活跃度
                        user.setActivityLevel(calculateActivityLevel(lastActiveTime, getPlayFrequency(statistics)));
                    }
                } catch (Exception e) {
                    log.warn("获取用户[{}]统计信息失败: {}", user.getId(), e.getMessage());
                }
                
                // 获取用户成就数量
                try {
                    List<?> achievements = gameAchievementService.getUserAchievements(user.getId());
                    user.setAchievementCount(achievements != null ? achievements.size() : 0);
                } catch (Exception e) {
                    log.warn("获取用户[{}]成就信息失败: {}", user.getId(), e.getMessage());
                }
                
                // 获取用户游戏偏好
                try {
                    List<Map<String, Object>> gameTypes = gameUserRecordService.getGameTypeDistribution(user.getId());
                    if (gameTypes != null && !gameTypes.isEmpty()) {
                        List<String> preferences = gameTypes.stream()
                                .limit(3)
                                .map(map -> (String) map.get("name"))
                                .collect(Collectors.toList());
                        user.setGamePreferences(preferences);
                    }
                } catch (Exception e) {
                    log.warn("获取用户[{}]游戏偏好失败: {}", user.getId(), e.getMessage());
                }
            }
        }
        
        // 排序处理
        if (StringUtils.isNotBlank(queryParams.getSortField())) {
            sortUserList(records, queryParams.getSortField(), queryParams.getSortOrder());
        }
        
        page.setRecords(records);
        return page;
    }

    @Override
    public GameUserInfo getUserInfo(Long id) {
        // 获取当前登录用户ID
        Long currentUserId = getCurrentUserId();
        
        // 如果未指定ID，则返回当前用户信息
        if (id == null) {
            id = currentUserId;
        }
        
        // 查询用户基本信息
        GameUserInfo userInfo = new GameUserInfo();
        
        try {
            // 从排行榜服务获取用户基本信息和积分
            userInfo = gameLeaderboardService.getUserPoints(id);
            
            if (userInfo != null) {
                // 获取用户统计信息
                GameUserStatisticsVO statistics = gameUserStatisticsService.getUserStatistics(id);
                if (statistics != null) {
                    userInfo.setTotalGames(statistics.getTotalGames());
                    userInfo.setTotalPlayTime(statistics.getTotalPlayTime() != null ? statistics.getTotalPlayTime().longValue() : 0L);
                    // 使用updateTime作为最后活跃时间
                    LocalDateTime lastActiveTime = getLastActiveTime(statistics);
                    userInfo.setLastActive(lastActiveTime);
                    
                    // 计算活跃度
                    userInfo.setActivityLevel(calculateActivityLevel(lastActiveTime, getPlayFrequency(statistics)));
                }
                
                // 获取用户成就数量
                List<?> achievements = gameAchievementService.getUserAchievements(id);
                userInfo.setAchievementCount(achievements != null ? achievements.size() : 0);
                
                // 获取用户游戏偏好
                List<Map<String, Object>> gameTypes = gameUserRecordService.getGameTypeDistribution(id);
                if (gameTypes != null && !gameTypes.isEmpty()) {
                    List<String> preferences = gameTypes.stream()
                            .map(map -> (String) map.get("name"))
                            .collect(Collectors.toList());
                    userInfo.setGamePreferences(preferences);
                }
            }
        } catch (Exception e) {
            log.error("获取用户详情信息失败", e);
        }
        
        return userInfo;
    }

    @Override
    public List<Map<String, Object>> getGameTypeDistribution(Long userId) {
        // 如果未指定用户ID，则取当前登录用户
        if (userId == null) {
            userId = getCurrentUserId();
        }
        
        // 从游戏记录服务获取游戏类型分布
        return gameUserRecordService.getGameTypeDistribution(userId);
    }

    @Override
    public List<Map<String, Object>> getActivityDistribution() {
        // 返回活跃度分布数据
        List<Map<String, Object>> result = new ArrayList<>();
        
        // 获取所有用户列表
        List<GameUserInfo> allUsers = getAllUsers();
        
        // 统计各活跃度用户数量
        Map<String, Integer> activityCounts = new HashMap<>();
        activityCounts.put("high", 0);
        activityCounts.put("medium", 0);
        activityCounts.put("low", 0);
        
        for (GameUserInfo user : allUsers) {
            String activityLevel = user.getActivityLevel();
            if (activityLevel != null) {
                activityCounts.put(activityLevel, activityCounts.getOrDefault(activityLevel, 0) + 1);
            }
        }
        
        // 构建返回结果
        for (Map.Entry<String, Integer> entry : activityCounts.entrySet()) {
            Map<String, Object> item = new HashMap<>();
            item.put("name", getActivityLevelText(entry.getKey()));
            item.put("value", entry.getValue());
            result.add(item);
        }
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getMonthlyTrend(Integer months) {
        List<Map<String, Object>> result = new ArrayList<>();
        
        // 获取当前日期
        LocalDateTime now = LocalDateTime.now();
        
        // 获取所有用户
        List<GameUserInfo> allUsers = getAllUsers();
        
        // 按月统计新增用户数量
        for (int i = months - 1; i >= 0; i--) {
            LocalDateTime monthStart = now.minusMonths(i).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
            LocalDateTime monthEnd = monthStart.plusMonths(1).minusNanos(1);
            
            // 计算当月新增用户数
            long newUserCount = allUsers.stream()
                    .filter(user -> user.getCreateTime() != null)
                    .filter(user -> user.getCreateTime().isAfter(monthStart) && user.getCreateTime().isBefore(monthEnd))
                    .count();
            
            Map<String, Object> item = new HashMap<>();
            item.put("month", monthStart.format(DateTimeFormatter.ofPattern("yyyy-MM")));
            item.put("count", newUserCount);
            result.add(item);
        }
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getPlayTimeDistribution() {
        List<Map<String, Object>> result = new ArrayList<>();
        
        // 获取所有用户
        List<GameUserInfo> allUsers = getAllUsers();
        
        // 定义时长区间（小时）
        int[] timeRanges = {1, 5, 10, 20, 50, 100, 200};
        
        // 统计各时长区间的用户数量
        Map<String, Integer> countMap = new HashMap<>();
        
        for (GameUserInfo user : allUsers) {
            long playTimeHours = user.getTotalPlayTime() != null ? user.getTotalPlayTime() / 3600 : 0;
            
            String range = null;
            if (playTimeHours < timeRanges[0]) {
                range = "< " + timeRanges[0] + "h";
            } else if (playTimeHours >= timeRanges[timeRanges.length - 1]) {
                range = ">= " + timeRanges[timeRanges.length - 1] + "h";
            } else {
                for (int i = 0; i < timeRanges.length - 1; i++) {
                    if (playTimeHours >= timeRanges[i] && playTimeHours < timeRanges[i + 1]) {
                        range = timeRanges[i] + "h - " + timeRanges[i + 1] + "h";
                        break;
                    }
                }
            }
            
            if (range != null) {
                countMap.put(range, countMap.getOrDefault(range, 0) + 1);
            }
        }
        
        // 构建返回结果
        for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
            Map<String, Object> item = new HashMap<>();
            item.put("range", entry.getKey());
            item.put("count", entry.getValue());
            result.add(item);
        }
        
        return result;
    }

    @Override
    public String exportUserData(GameUserInfoQuery queryParams) {
        // 获取用户数据
        Page<GameUserInfo> page = getUserInfoPage(queryParams);
        List<GameUserInfo> users = page.getRecords();
        
        // 导出数据逻辑（实际实现中应该生成Excel文件并上传到文件服务）
        // 这里返回模拟的文件URL
        String fileName = "用户数据_" + formatDate(new Date()) + ".xlsx";
        log.info("导出用户数据: {}, 共{}条记录", fileName, users.size());
        
        return "https://example.com/exports/" + fileName;
    }

    @Override
    public String exportAnalysisReport() {
        // 获取分析数据
        List<Map<String, Object>> typeDistribution = getGameTypeDistribution(null);
        List<Map<String, Object>> activityDistribution = getActivityDistribution();
        List<Map<String, Object>> monthlyTrend = getMonthlyTrend(12);
        List<Map<String, Object>> playTimeDistribution = getPlayTimeDistribution();
        
        // 导出报告逻辑（实际实现中应该生成PDF报告并上传到文件服务）
        // 这里返回模拟的文件URL
        String fileName = "用户分析报告_" + formatDate(new Date()) + ".pdf";
        log.info("导出分析报告: {}", fileName);
        
        return "https://example.com/reports/" + fileName;
    }
    
    /**
     * 获取当前用户ID
     * 临时方法，替代UserUtils.getUserId()
     */
    private Long getCurrentUserId() {
        // 临时返回一个默认值，实际项目中应该从安全上下文中获取
        return 1L;
    }
    
    /**
     * 格式化日期为字符串
     */
    private String formatDate(Date date) {
        return new SimpleDateFormat("yyyyMMddHHmmss").format(date);
    }
    
    /**
     * 获取用户最后活跃时间
     * 由于GameUserStatisticsVO没有getLastPlayTime方法，使用dailyPlayTime列表中的最后一条记录或当前时间
     */
    private LocalDateTime getLastActiveTime(GameUserStatisticsVO statistics) {
        if (statistics == null) {
            return LocalDateTime.now().minusDays(30); // 默认为30天前
        }
        
        List<Map<String, Object>> dailyPlayTime = statistics.getDailyPlayTime();
        if (dailyPlayTime != null && !dailyPlayTime.isEmpty()) {
            // 如果有每日游戏时长记录，取最后一条记录的日期
            try {
                String dateStr = (String) dailyPlayTime.get(dailyPlayTime.size() - 1).get("date");
                if (dateStr != null) {
                    return LocalDateTime.parse(dateStr + " 12:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                }
            } catch (Exception e) {
                log.warn("解析最后活跃时间失败", e);
            }
        }
        
        // 没有记录，则返回当前时间前7天（表示最近有活动）
        return LocalDateTime.now().minusDays(7);
    }
    
    /**
     * 获取用户游戏频率
     * 由于GameUserStatisticsVO没有getPlayFrequency方法，根据dailyPlayTime列表计算
     */
    private Integer getPlayFrequency(GameUserStatisticsVO statistics) {
        if (statistics == null) {
            return 0;
        }
        
        List<Map<String, Object>> dailyPlayTime = statistics.getDailyPlayTime();
        if (dailyPlayTime != null && !dailyPlayTime.isEmpty()) {
            // 计算过去30天内有游戏记录的天数，除以4，得到每周平均游戏天数
            int activeDays = 0;
            for (Map<String, Object> dayRecord : dailyPlayTime) {
                if (dayRecord.get("value") != null && ((Number) dayRecord.get("value")).intValue() > 0) {
                    activeDays++;
                }
            }
            
            // 计算每周平均值
            return Math.round(activeDays / 4.0f);
        }
        
        return 0;
    }
    
    /**
     * 计算用户活跃度
     *
     * @param lastActiveTime 最后游戏时间
     * @param playFrequency 游戏频率（每周平均游戏次数）
     * @return 活跃度（high, medium, low）
     */
    private String calculateActivityLevel(LocalDateTime lastActiveTime, Integer playFrequency) {
        if (lastActiveTime == null) {
            return "low";
        }
        
        // 最后游戏时间在7天内，且平均每周游戏次数大于等于5次，视为高度活跃
        if (lastActiveTime.isAfter(LocalDateTime.now().minusDays(7)) && (playFrequency != null && playFrequency >= 5)) {
            return "high";
        }
        
        // 最后游戏时间在30天内，且平均每周游戏次数大于等于2次，视为中度活跃
        if (lastActiveTime.isAfter(LocalDateTime.now().minusDays(30)) && (playFrequency != null && playFrequency >= 2)) {
            return "medium";
        }
        
        // 其他情况视为低度活跃
        return "low";
    }
    
    /**
     * 获取活跃度文本
     *
     * @param level 活跃度代码
     * @return 活跃度文本
     */
    private String getActivityLevelText(String level) {
        Map<String, String> texts = new HashMap<>();
        texts.put("high", "高度活跃");
        texts.put("medium", "中度活跃");
        texts.put("low", "低度活跃");
        return texts.getOrDefault(level, "未知");
    }
    
    /**
     * 对用户列表进行排序
     *
     * @param users     用户列表
     * @param sortField 排序字段
     * @param sortOrder 排序方式
     */
    private void sortUserList(List<GameUserInfo> users, String sortField, String sortOrder) {
        if (users == null || users.isEmpty() || StringUtils.isBlank(sortField)) {
            return;
        }
        
        boolean isAsc = !"descending".equals(sortOrder);
        
        users.sort((a, b) -> {
            int result = 0;
            
            switch (sortField) {
                case "username":
                    result = compareString(a.getUsername(), b.getUsername());
                    break;
                case "level":
                    result = compareInteger(a.getLevel(), b.getLevel());
                    break;
                case "totalGames":
                    result = compareInteger(a.getTotalGames(), b.getTotalGames());
                    break;
                case "totalPlayTime":
                    result = compareLong(a.getTotalPlayTime(), b.getTotalPlayTime());
                    break;
                case "lastActive":
                    result = compareDateTime(a.getLastActive(), b.getLastActive());
                    break;
                case "activityLevel":
                    result = compareActivityLevel(a.getActivityLevel(), b.getActivityLevel());
                    break;
                case "achievementCount":
                    result = compareInteger(a.getAchievementCount(), b.getAchievementCount());
                    break;
                case "points":
                    result = compareInteger(a.getPoints(), b.getPoints());
                    break;
                default:
                    break;
            }
            
            return isAsc ? result : -result;
        });
    }
    
    /**
     * 比较字符串
     */
    private int compareString(String a, String b) {
        if (a == null && b == null) return 0;
        if (a == null) return -1;
        if (b == null) return 1;
        return a.compareTo(b);
    }
    
    /**
     * 比较整数
     */
    private int compareInteger(Integer a, Integer b) {
        if (a == null && b == null) return 0;
        if (a == null) return -1;
        if (b == null) return 1;
        return a.compareTo(b);
    }
    
    /**
     * 比较长整数
     */
    private int compareLong(Long a, Long b) {
        if (a == null && b == null) return 0;
        if (a == null) return -1;
        if (b == null) return 1;
        return a.compareTo(b);
    }
    
    /**
     * 比较日期时间
     */
    private int compareDateTime(LocalDateTime a, LocalDateTime b) {
        if (a == null && b == null) return 0;
        if (a == null) return -1;
        if (b == null) return 1;
        return a.compareTo(b);
    }
    
    /**
     * 比较活跃度
     */
    private int compareActivityLevel(String a, String b) {
        if (a == null && b == null) return 0;
        if (a == null) return -1;
        if (b == null) return 1;
        
        // 活跃度优先级: high > medium > low
        Map<String, Integer> priority = new HashMap<>();
        priority.put("high", 3);
        priority.put("medium", 2);
        priority.put("low", 1);
        
        Integer priorityA = priority.getOrDefault(a, 0);
        Integer priorityB = priority.getOrDefault(b, 0);
        
        return priorityA.compareTo(priorityB);
    }
    
    /**
     * 获取所有用户列表
     * 注意：实际应用中应该分页查询或使用缓存
     */
    private List<GameUserInfo> getAllUsers() {
        // 在实际应用中，这里应该从数据库分页查询所有用户
        // 为了演示，这里使用分页查询获取前100个用户
        GameUserInfoQuery query = new GameUserInfoQuery();
        query.setPageNum(1);
        query.setPageSize(100);
        
        Page<GameUserInfo> page = getUserInfoPage(query);
        return page.getRecords();
    }
} 